package com.jing.servlets;

import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;
import org.apache.log4j.Logger;

import com.jing.comm.AppComm;


/**
 * 附件上传servlet
 * @author jing.yue
 * @since 2012-07-26
 * @version 1.0.0
 */
public class UploadServlet extends HttpServlet {

	private static final long serialVersionUID = 7480621143378258586L;

	private static final Logger logger = Logger.getLogger(UploadServlet.class);

	// 字符集编码
	private static String encoding = "UTF-8";

	public void init() throws ServletException {
		super.init();
	}

	/**
	 * doGet
	 *
	 * @param request
	 * @param res
	 * @param session
	 * @throws ServletException
	 * @throws IOException
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	/**
	 * doPost
	 * @param request
	 * @param reponse
	 * @throws ServletException ,
	 *             IOException
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html");
		response.setCharacterEncoding(encoding);

		//String realDir = request.getSession().getServletContext().getRealPath("/");
		String realDir = AppComm.saveImageRoot;

		String contextpath = request.getContextPath();
		String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + contextpath + "/";

		//指定的文件名称
		String paramFileName = null;
		//限制类型
		String imgConfineType = null;
		//限制宽度
		String imgConfineWidth = null;
		//限制高度
		String imgConfineHeight = null;
		try {
			String filePath = "upload_images/poster";
			String realPath = realDir + filePath;
			//判断路径是否存在，不存在则创建
			File dir = new File(realPath);
			if(!dir.isDirectory())
				dir.mkdirs();

			if(ServletFileUpload.isMultipartContent(request)){

				DiskFileItemFactory dff = new DiskFileItemFactory();
				dff.setRepository(dir);
				dff.setSizeThreshold(1024000);
				ServletFileUpload sfu = new ServletFileUpload(dff);
				FileItemIterator fii = null;
				fii = sfu.getItemIterator(request);
				//图片地址
				String url = "";
				String fileName = "";
				String msg = "";
				String error = "";
				String realFileName="";
				while(fii.hasNext()){
					FileItemStream fis = fii.next();

					try{
						if(!fis.isFormField() && fis.getName().length()>0){
							fileName = fis.getName();
							//判断文件名是否存在“/”或“\\”
							int index = (fileName.lastIndexOf("/") != -1 ? fileName.lastIndexOf("/") : fileName.lastIndexOf("\\"));
							if(index > -1) {
								fileName = fileName.substring(index + 1);
							}
							else if(index == -1 && fileName.lastIndexOf(":") > -1) {
								fileName = fileName.substring(fileName.lastIndexOf(":") + 1);
							}

							Pattern reg = Pattern.compile("[.]jpg|png|jpeg|gif$");
							Matcher matcher=reg.matcher(fileName);
							if(!matcher.find()) {
								error = "文件类型不允许!";
								break;
							}
							//文件名称
							if(paramFileName == null || "".equals(paramFileName.trim())) {
								realFileName = new Date().getTime() + fileName.substring(fileName.lastIndexOf("."), fileName.length());
							} else {
								realFileName = paramFileName;
							}
							url = realPath + "/" + realFileName;

							InputStream inputStream = fis.openStream();

							//判断图片大小
							if(imgConfineType != null && !"".equals(imgConfineType.trim())) {
								BufferedImage image = ImageIO.read(inputStream);
								//为等于
								if("=".equals(imgConfineType.trim()) &&
										(image.getWidth() != Integer.parseInt(imgConfineWidth) || image.getHeight() != Integer.parseInt(imgConfineHeight)) ) {
									error = "请上传宽" + imgConfineWidth + ", 高" + imgConfineHeight + "的图片!";
									msg = error;
									break;
								}
								//为小于等于
								else if("<=".equals(imgConfineType.trim()) &&
										(image.getWidth() > Integer.parseInt(imgConfineWidth) || image.getHeight() > Integer.parseInt(imgConfineHeight)) ) {
									error = "请上传宽小于等于" + imgConfineWidth + ", 高小于等于" + imgConfineHeight + "的图片!";
									msg = error;
									break;
								}
								//为大于等于
								else if(">=".equals(imgConfineType.trim()) &&
										(image.getWidth() < Integer.parseInt(imgConfineWidth) || image.getHeight() < Integer.parseInt(imgConfineHeight)) ) {
									error = "请上传宽大于等于" + imgConfineWidth + ", 高大于等于" + imgConfineHeight + "的图片!";
									msg = error;
									break;
								}

								//从BufferedImage得到InputStream对象
								ByteArrayOutputStream bs = new ByteArrayOutputStream();
								ImageOutputStream imOut = ImageIO.createImageOutputStream(bs);
								ImageIO.write(image, fileName.substring(fileName.lastIndexOf(".") + 1), imOut);
								inputStream = new ByteArrayInputStream(bs.toByteArray());
							}

							//获得文件输入流
							BufferedInputStream in = new BufferedInputStream(inputStream);
							FileOutputStream a = new FileOutputStream(new File(url));
							BufferedOutputStream output = new BufferedOutputStream(a);

							//开始把文件写到你指定的上传文件夹
							Streams.copy(in, output, true);

							msg = "上传成功!";
						}else{
							String fname = fis.getFieldName();

							BufferedInputStream in = new BufferedInputStream(fis.openStream());
							byte c [] = new byte[20];
							int n = 0;
							while((n=in.read(c)) != -1){
								//指定的文件名称
								if(fname.indexOf("fileName") != -1){
									paramFileName = new String(c,0,n);
									break;
								}
								//限制类型
								else if(fname.indexOf("imgConfineType") != -1) {
									imgConfineType = new String(c,0,n);
									break;
								}
								//限制宽度
								else if(fname.indexOf("imgConfineWidth") != -1) {
									imgConfineWidth = new String(c,0,n);
									break;
								}
								//限制高度
								else if(fname.indexOf("imgConfineHeight") != -1) {
									imgConfineHeight = new String(c,0,n);
									break;
								}
							}
						}

					}catch(Exception e){
						e.printStackTrace();
						error = "上传文件异常!";
					}
				}
				if(fileName == null || "".equals(fileName.trim())) {
					error = "请选择上传文件";
					msg = error;
				}
				response.setStatus(200);
				StringBuffer result = new StringBuffer();
				result.append("{filename:'" + realFileName + "',");
				result.append("orgFilename:'" + fileName + "',");
				result.append("src:'" + basePath + filePath + "/" + realFileName + "',");
				result.append("url:'" + filePath + "/" + realFileName + "',");
				result.append("msg:'" + msg + "',");
				result.append("error:'" + error + "'}");
				logger.info("response: " + result.toString());
				response.getWriter().print(result.toString());
			}
		}catch(Exception ee) {
			ee.printStackTrace();
		}
	}
}
